﻿using System.ComponentModel;
using System.Reflection;

namespace System
{
    /// <summary>
    /// 枚举扩展
    /// </summary>
    public static class EnumExtension
    {
        /// <summary>
        /// 获取枚举值的描述
        /// </summary>
        /// <param name="enumValue">枚举值</param>
        /// <returns>描述</returns>
        public static string GetDescription(this Enum enumValue)
        {
            string value = enumValue.ToString();
            FieldInfo field = enumValue.GetType().GetField(value);
            object[] objs = field.GetCustomAttributes(typeof(DescriptionAttribute), false);
            if (objs == null || objs.Length == 0)
            {
                return value;
            }

            DescriptionAttribute descriptionAttribute = (DescriptionAttribute)objs[0];
            return descriptionAttribute.Description;
        }

        /// <summary>
        /// 转换int值为指定的枚举类型
        /// </summary>
        /// <typeparam name="T">对应的枚举类型</typeparam>
        /// <param name="value">int</param>
        /// <returns>指定的枚举类型</returns>
        public static T TransformIntToEnum<T>(this int value)
        {
            Type type = typeof(T);
            Array fields = type.GetEnumValues();
            foreach (var item in fields)
            {
                if (Convert.ToInt32(item) == Convert.ToInt32(value))
                {
                    return (T)item;
                }
            }

            throw new ArgumentException($"cannot transform value:{value} to Enum: {type.Name}");
        }

        /// <summary>
        /// 根据枚举的描述获取枚举值
        /// </summary>
        /// <typeparam name="T">枚举类型</typeparam>
        /// <param name="description">描述</param>
        /// <returns>枚举</returns>
        public static T GetEnumByDescription<T>(this string description)
        {
            FieldInfo[] fields = typeof(T).GetFields();
            Type descriptionType = typeof(DescriptionAttribute);
            foreach (FieldInfo field in fields)
            {
                bool isDefined = field.IsDefined(descriptionType);
                var test = field.GetCustomAttribute(descriptionType, false);
                if (isDefined && (test as DescriptionAttribute).Description.ToLower() == description.ToLower())
                {
                    object obj = field.GetCustomAttribute(descriptionType, false);
                    T t = (T)field.GetValue(obj);
                    return t;
                }
            }

            throw new ArgumentException($"cannot get enum value from description: {description}");
        }
    }
}
